package model;

import java.awt.Color;
import java.awt.image.BufferedImage;

public class ImageProcessor {

	public static final int NEGATIVE = 0;
	public static final int GRAY_SCALE_YIQ = 1;
	public static final int GRAY_SCALE_AVERAGE = 2;
	public static final int SEPIA = 3;
	public static final int RED = 4;
	public static final int GREEN = 5;
	public static final int BLUE = 6;

	private BufferedImage image;
	private int r, g, b;
	private Color color;

	public ImageProcessor(BufferedImage image) {
		this.image = image;
	}

	public BufferedImage applyNegativeFilter() {
		BufferedImage bufferedImage = new BufferedImage(image.getWidth(),
				image.getHeight(), image.getType());

		for (int i = 0; i < image.getWidth(); i++) {

			for (int j = 0; j < image.getHeight(); j++) {

				color = new Color(image.getRGB(i, j));

				r = 255 - color.getRed();
				g = 255 - color.getGreen();
				b = 255 - color.getBlue();

				bufferedImage.setRGB(i, j, new Color(r, g, b).getRGB());
			}
		}
		return bufferedImage;
	}

	public BufferedImage applyGrayScaleFilterYIQ() {
		BufferedImage bufferedImage = new BufferedImage(image.getWidth(),
				image.getHeight(), image.getType());

		for (int i = 0; i < image.getWidth(); i++) {

			for (int j = 0; j < image.getHeight(); j++) {

				color = new Color(image.getRGB(i, j));

				r = (int) (0.299 * color.getRed());
				g = (int) (0.587 * color.getGreen());
				b = (int) (0.114 * color.getBlue());
				int gray = r + g + b;

				bufferedImage
						.setRGB(i, j, new Color(gray, gray, gray).getRGB());
			}
		}
		return bufferedImage;
	}

	public BufferedImage applyGrayScaleFilterAverage(int average) {
		BufferedImage bufferedImage = new BufferedImage(image.getWidth(),
				image.getHeight(), image.getType());

		for (int i = 0; i < image.getWidth(); i++) {

			for (int j = 0; j < image.getHeight(); j++) {

				color = new Color(image.getRGB(i, j));

				r = color.getRed();
				g = color.getGreen();
				b = color.getBlue();
				int med = (r + g + b) / average;
				med = med > 255 ? 255 : med;

				bufferedImage.setRGB(i, j, new Color(med, med, med).getRGB());
			}
		}
		return bufferedImage;
	}

	public BufferedImage applySepiaFilter() {
		BufferedImage bufferedImage = new BufferedImage(image.getWidth(),
				image.getHeight(), image.getType());

		for (int i = 0; i < image.getWidth(); i++) {

			for (int j = 0; j < image.getHeight(); j++) {

				color = new Color(image.getRGB(i, j));

				r = (int) (color.getRed() * 0.393 + color.getGreen() * 0.769 + color
						.getBlue() * 0.189);
				g = (int) (color.getRed() * 0.349 + color.getGreen() * 0.686 + color
						.getBlue() * 0.168);
				b = (int) (color.getRed() * 0.272 + color.getGreen() * 0.534 + color
						.getBlue() * 0.131);

				bufferedImage.setRGB(i, j, new Color((r > 255) ? 255 : r,
						(g > 255) ? 255 : g, (b > 255) ? 255 : b).getRGB());
			}
		}
		return bufferedImage;
	}

	public BufferedImage applyRedFilter() {
		BufferedImage bufferedImage = new BufferedImage(image.getWidth(),
				image.getHeight(), image.getType());

		for (int i = 0; i < image.getWidth(); i++) {

			for (int j = 0; j < image.getHeight(); j++) {

				color = new Color(image.getRGB(i, j));

				r = color.getRed();
				g = color.getGreen();
				b = color.getBlue();

				if (r < b) {
					if (b > g) {
						int color = r;
						r = b;
						b = color;
					} else {
						int color = r;
						r = g;
						g = color;
					}
				} else if (r < g) {
					if (g > b) {
						int color = r;
						r = g;
						g = color;
					} else {
						int color = r;
						r = b;
						b = color;
					}
				}

				bufferedImage.setRGB(i, j, new Color(r, g, b).getRGB());
			}
		}
		return bufferedImage;
	}

	public BufferedImage applyGreenFilter() {
		BufferedImage bufferedImage = new BufferedImage(image.getWidth(),
				image.getHeight(), image.getType());

		for (int i = 0; i < image.getWidth(); i++) {

			for (int j = 0; j < image.getHeight(); j++) {

				color = new Color(image.getRGB(i, j));

				r = color.getRed();
				g = color.getGreen();
				b = color.getBlue();

				if (g < r) {
					if (r > b) {
						int color = g;
						g = r;
						r = color;
					} else {
						int color = g;
						g = b;
						b = color;
					}
				} else if (g < b) {
					if (b > r) {
						int color = g;
						g = b;
						b = color;
					} else {
						int color = g;
						g = r;
						r = color;
					}
				}

				bufferedImage.setRGB(i, j, new Color(r, g, b).getRGB());
			}
		}
		return bufferedImage;
	}

	public BufferedImage applyBlueFilter() {
		BufferedImage bufferedImage = new BufferedImage(image.getWidth(),
				image.getHeight(), image.getType());

		for (int i = 0; i < image.getWidth(); i++) {

			for (int j = 0; j < image.getHeight(); j++) {

				color = new Color(image.getRGB(i, j));

				r = color.getRed();
				g = color.getGreen();
				b = color.getBlue();

				if (b < r) {
					if (r > g) {
						int color = b;
						b = r;
						r = color;
					} else {
						int color = b;
						b = g;
						g = color;
					}
				} else if (b < g) {
					if (g > r) {
						int color = b;
						b = g;
						g = color;
					} else {
						int color = b;
						b = r;
						r = color;
					}
				}

				bufferedImage.setRGB(i, j, new Color(r, g, b).getRGB());
			}
		}
		return bufferedImage;
	}

	public BufferedImage getImage() {
		return image;
	}

	public void setImage(BufferedImage image) {
		this.image = image;
	}
}
